/**
 * 
 */
package ch.baeni.jee.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

import ch.baeni.jee.data.LinkRepository;
import ch.baeni.jee.model.Link;
import ch.baeni.jee.service.LinkService;
import ch.baeni.jee.util.ListWrapper;

/**
 * ManagedBean fuer die Seite links.xhtml
 * 
 * @author Benjamin
 * 
 */
@ManagedBean
@ViewScoped
public class LinkBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private static final String SUCCESS = "links";
	private static final String ERROR = "links";
	private static final String HTTP = "http://";

	@Inject
	private FacesContext facesContext;

	@Inject
	private LinkService linkService;

	@Inject
	private LinkRepository linkRep;

	@Produces
	@Named
	private Link link;

	private String syncUrl;

	public Link getLink() {
		return link;
	}

	public void setLink(Link link) {
		this.link = link;
	}

	@PostConstruct
	public void initNewLink() {
		link = new Link();
	}

	/**
	 * Link speichern
	 * 
	 * @return
	 */
	public String save() {
		try {
			// Pruefen ob Prefix vorhanden, wenn nein --> http:// ergaenzen
			int i = link.getLinktext().indexOf("://");
			if (i == -1) {
				link.setLinktext(HTTP + link.getLinktext());
			}
			linkService.saveLink(link);
			FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_INFO,
					"Value stored in Database", "Submit successful");
			facesContext.addMessage(null, m);
			initNewLink();
			return SUCCESS;
		} catch (Exception e) {
			return ERROR;
		}
	}

	/**
	 * Link loeschen
	 * 
	 * @param linkToDelete
	 *            Zu loeschender Link
	 */
	public void deleteLink(Link linkToDelete) {
		linkService.deleteLink(linkToDelete);
	}

	/**
	 * Link editieren
	 * 
	 * @param linkToEdit
	 *            Zu editierender Link
	 */
	public void editLink(Link linkToEdit) {
		this.link = linkToEdit;
	}

	/**
	 * Gibt eine Liste mit allen Links zurueck
	 * 
	 * @return <code>List</code> Liste mit allen Links
	 */
	public List<Link> getAllLinks() {
		return linkRep.findAllLinksOrderedByName();
	}

	/**
	 * Links syncronisieren
	 */
	public void synchronize() {
		HttpURLConnection connection = null;
		try {
			// Verbindung zu Webservice herstellen
			URL url = new URL(getSyncUrl());
			connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Accept", "application/xml");
			// Result in ListWrapper unmarshallen
			JAXBContext jc = JAXBContext.newInstance(ListWrapper.class);
			InputStream xml = connection.getInputStream();
			ListWrapper lw = (ListWrapper) jc.createUnmarshaller().unmarshal(
					xml);
			// Verbindung trennen
			connection.disconnect();
			synchronizeList(lw.getLinkList());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Listen synchronisieren
	 * 
	 * @param linkList
	 *            Liste von Extern
	 */
	private void synchronizeList(List<Link> externalList) {
		List<Link> internalList = linkRep.findAllLinksOrderedByName();
		for (Link extLink : externalList) {
			boolean save = true;
			for (Link intLink : internalList) {
				// Wenn Link bereits in lokaler Liste vorhanden ist nicht
				// speichern
				if (extLink.getLinktext().equals(intLink.getLinktext())) {
					save = false;
					break;
				}
			}
			if (save) {
				linkService.saveLink(extLink);
			}
		}
	}

	public String getSyncUrl() {
		return syncUrl;
	}

	public void setSyncUrl(String syncUrl) {
		this.syncUrl = syncUrl;
	}
}
